package com.hcj.springcloud;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * 延时队列测试：
 * 验证，在延时很小的时候，对cpu的影响
 */
public class DelayQueueTest {
    public DelayQueueTest() {
    }

    private static long id = 0;
    protected static final int COUNT = 50;
    static DelayQueue<MyDelayed> dq = new DelayQueue<MyDelayed>();

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.interrupted()) {
                    try {
                        List<MyDelayed> list = new ArrayList<MyDelayed>();
                        list.add(dq.take());
                        dq.drainTo(list);
                        for (int i = 0, size = list.size(); i < size; i++) {
                        }
                        Thread.sleep(5L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.interrupted()) {
                    for (int i = 0; i < COUNT; i++) {
                        dq.add(new MyDelayed(id++, 100));//这里如果是很随机的，出现的占用cpu的概率很低的
                    }
                    try {
                        Thread.sleep(50L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }


    static class MyDelayed implements Delayed {
        long id;
        long delay;
        long timeout;

        public MyDelayed(long id, long timeout) {
            this.id = id;
            this.timeout = timeout;
            this.delay = timeout + System.currentTimeMillis();
        }

        @Override
        public int compareTo(Delayed o) {
            MyDelayed md = (MyDelayed) o;
            return md.delay < this.delay ? 1 : -1;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return this.delay - System.currentTimeMillis();//unit.convert(this.delay - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        public String toString() {
            return this.id + " delay " + timeout + " ms ";
        }
    }
}
